type Listener<T extends any[] = any[]> = (...args: T) => void;

class Emitter {
    private map = new Map<string, Set<Listener>>();

    on(evt: string, fn: Listener) {
        (this.map.get(evt) ?? this.map.set(evt, new Set()).get(evt)!)!.add(fn);
        return () => this.off(evt, fn);
    }

    off(evt: string, fn: Listener) {
        this.map.get(evt)?.delete(fn);
    }

    emit(evt: string, ...args: any[]) {
        this.map.get(evt)?.forEach(fn => fn(...args));
    }
}

export default Emitter;
